/*
 * @Author: tianz 
 * @Date: 2018-11-15 20:19:11 
 * @Last Modified by: tianz
 * @Last Modified time: 2018-11-16 13:46:04
 * 
 * @Description: WebServer类定义
 */

#include "webServer.h"

namespace PTLR{

    WebServer::WebServer(std::string url)
    {
        utility::string_t address = url;
        web::uri_builder uri(address);
        auto addr = uri.to_uri().to_string();

        m_listener = new web::http::experimental::listener::http_listener(addr);
        m_listener->support(web::http::methods::GET, std::bind(&WebServer::handle_get, this, std::placeholders::_1));
        m_listener->support(web::http::methods::POST, std::bind(&WebServer::handle_post, this, std::placeholders::_1));
        m_listener->support(web::http::methods::PUT, std::bind(&WebServer::handle_put, this, std::placeholders::_1));
        m_listener->support(web::http::methods::DEL, std::bind(&WebServer::handle_del, this, std::placeholders::_1));
    }

    WebServer::~WebServer()
    {
        delete m_listener;
    }

    void WebServer::handle_get(web::http::http_request message)
    {
        ucout << "Method: " << message.method() << std::endl;
        ucout << "URI: " << web::http::uri::decode(message.relative_uri().path()) << std::endl;
        ucout << "Query: " << web::http::uri::decode(message.relative_uri().query()) << std::endl << std::endl;
        message.reply(web::http::status_codes::OK, web::json::value("ACCEPTED"));
    }

    void WebServer::handle_post(web::http::http_request message)
    {
        // 1. 请求基本信息输出，fot test
        static int callTimes = 0;
        ucout << std::endl << "*****************************"<< std::endl;
        ucout << "callTimes: " << ++callTimes << std::endl;
        ucout << "Method: " << message.method() << std::endl;
        ucout << "URI: " << web::http::uri::decode(message.relative_uri().path()) << std::endl;
        ucout << "Query: " << web::http::uri::decode(message.relative_uri().query()) << std::endl;
        ucout << "headers: " << web::http::uri::decode(message.headers().content_type()) << std::endl;

        // 2. 解析Http-Request-Body
        // 
        // 以下述body为例解析
        // {
        //     "imageUrl": "https://example.jpg",
        //     "localSave": true,
        //     "detetcDog": 
        //     {
        //         "threshold": 0.5
        //     }
        // }        
        std::error_code errorCode;
        web::json::value requestBody = web::json::value::parse(message.extract_string().get(), errorCode);
        web::json::value obj;
        obj["resultCode"] = web::json::value::number (errorCode.value());
        if(errorCode.value() > 0) // Body解析出错
        {
            obj["result"] = web::json::value::string(U("请求body错误"));
            message.reply(web::http::status_codes::OK, obj.serialize(), "application/json; charset=utf-8");
        }
        else// Body解析
        {
            if(requestBody.has_field("imageUrl")) // string类型value
            {
                ucout << "requestBody[imageUrl]: " << requestBody.at("imageUrl").as_string() << std::endl;
            }
            if(requestBody.has_field("localSave")) // bool类型value
            {
                ucout << "requestBody[localSave]: " << requestBody.at("localSave").as_bool() << std::endl;
            }
            if(requestBody.has_field("detetcDog")) // object类型value
            {
                ucout << "requestBody[detetcDog]: " << requestBody.at("detetcDog").serialize() << std::endl;
                 web::json::value detetcDogJson = requestBody.at("detetcDog");
                if(detetcDogJson.has_field("threshold")) // double类型value
                {
                    ucout << "requestBody[detetcDog][threshold]: " << detetcDogJson.at("threshold").as_double() << std::endl;
                }
            }

            // 生成结果
            obj["result"] = web::json::value::string(U("请求成功"));
            message.reply(web::http::status_codes::OK, obj.serialize(), "application/json; charset=utf-8");
        }
    }

    void WebServer::handle_put(web::http::http_request message)
    {
        ucout << "Method: " << message.method() << std::endl;
        ucout << "URI: " << web::http::uri::decode(message.relative_uri().path()) << std::endl;
        ucout << "Query: " << web::http::uri::decode(message.relative_uri().query()) << std::endl << std::endl;
        message.reply(web::http::status_codes::OK, web::json::value("PUT"));
    }

    void WebServer::handle_del(web::http::http_request message)
    {
        ucout << "Method: " << message.method() << std::endl;
        ucout << "URI: " << web::http::uri::decode(message.relative_uri().path()) << std::endl;
        ucout << "Query: " << web::http::uri::decode(message.relative_uri().query()) << std::endl << std::endl;
        message.reply(web::http::status_codes::OK, web::json::value("DELETE"));
    }

    pplx::task<void> WebServer::open()
    {
        return m_listener->open();
    }

    pplx::task<void> WebServer::close()
    {
        return m_listener->close();
    }

} // namespace PTLR